#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "usart.h" //forӲ�⴮��ʹ��
#include "stdlib.h"
#include "libmodbus_rtu_slave.h"
modbus_slave_t *modbus_slave_creat(void *rtu_ctx, uint8_t slave_addr)
{
    modbus_slave_t *me = MODBUS_MALLOC(sizeof(modbus_slave_t));
    if (me == NULL)
    {
        return NULL;
    }
    me->rtu_slave_ctx = modbus_new_rtu(rtu_ctx, "COM", 115200, 'N', 8, 1); // ���ڲ�������
    me->slave_mapping = modbus_mapping_new(16, 16, 16, 16);                // 
                                                                           // me->slave_mapping =    modbus_mapping_new_start_address(12,16 ,12 ,12,12,12,12,12);
    // me->slave_mapping =    modbus_mapping_new_start_address(10,16 ,10 ,16,10,16,10,16);
    modbus_set_error_recovery(me->rtu_slave_ctx,
                              (MODBUS_ERROR_RECOVERY_LINK |
                               MODBUS_ERROR_RECOVERY_PROTOCOL));
    //	modbus_set_debug(me->rtu_slave_ctx, TRUE);
    /*���ôӻ���ַ*/
    modbus_set_slave(me->rtu_slave_ctx, slave_addr);
    me->rtu_addr = slave_addr;
    return me;
}
/*modbus�ӻ�*/
modbus_slave_t *modbus_slave_ctx;
/*modbus rtu����*/
uint16_t modbus_rtu_send_uart(void *ctx, void *data, uint16_t count)
{
    if (sizeof(data) > 0)
    {
      //HAL_UART_Transmit_DMA(&huart1, data, count);
			Uart_DMA_TX(data,count);
			
    }
    return count;
}

/*modbus rtu����*/
uint16_t modbus_rtu_handle(void *ctx, void *data, uint16_t count)
{
    modbus_reply(modbus_slave_ctx->rtu_slave_ctx, data, count, modbus_slave_ctx->slave_mapping);
    return count;
}

int modbus_choose_send(uint8_t ch)
{
    modbus_set_send(modbus_slave_ctx->rtu_slave_ctx, (int (*)(modbus_t *ctx, const uint8_t *req, int req_length))modbus_rtu_send_uart);
    return ch;
}

void modbus_rtu_init(uint8_t addr)
{

    /*����MODBUS�̣߳� rtu�������� dev_mb_rtu*/
    modbus_slave_ctx = modbus_slave_creat(NULL, addr);
    /*����modbus ���ͺ���*/
    if (modbus_slave_ctx != NULL)
    {
        modbus_set_send(modbus_slave_ctx->rtu_slave_ctx, (int (*)(modbus_t *ctx, const uint8_t *req, int req_length))modbus_rtu_send_uart);
    }
}
//��������
uint8_t tab[10] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
uint8_t tab_input[10] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
uint16_t tab_re1[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
uint16_t tab_input_re[10] = {1000, 900, 800, 700, 600, 500, 400, 300, 200, 100};

/**
 * ���� Modbus ���豸��ӳ�䡣
 *
 * @param tab_map ָ�� modbus_mapping_t �ṹ��ָ�룬��ʾ Modbus ���豸��ӳ�䡣
 * @param tab ���ڸ�����Ȧ�����顣���Ϊ NULL������������Ȧ��
 * @param tab_input ���ڸ�������״̬�����顣���Ϊ NULL��������������״̬��
 * @param tab_re ���ڸ��±��ּĴ��������顣���Ϊ NULL���������±��ּĴ�����
 * @param tab_input_re ���ڸ�������Ĵ��������顣���Ϊ NULL��������������Ĵ�����
 *
 * @return ������еĸ��¶��ɹ������� 0����� tab_map Ϊ NULL������ -1��
 */
uint16_t slave_update(modbus_mapping_t *tab_map, uint8_t *tab, uint8_t *tab_input, uint16_t *tab_re, uint16_t *tab_input_re, uint8_t len)
{
    uint16_t tab_length = len;
    uint16_t tab_input_length = len;
    uint16_t tab_re_length = len;
    uint16_t tab_input_re_length = len;
    //uint16_t mapping_addr_offset;//mapping Offset address
    
    if (tab_map == NULL)
    {
        return 0;
    }
    // ������Ȧ
    if (tab != NULL && tab_length > 0)
    {
        for (int i = 0; i < tab_length; i++)
        {
            // tab_map->tab_bits[i] = tab[i];
            tab[i] = tab_map->tab_bits[i]; // �������
        }
    }

    // ��������״̬
    if (tab_input != NULL && tab_input_length > 0)
    {
        for (int i = 0; i < tab_input_length; i++)
        {
            tab_map->tab_input_bits[i] = tab_input[i];
        }
    }

    // ���±��ּĴ���
    if (tab_re != NULL && tab_re_length > 0)
    {
        for (int i = 0; i < tab_re_length; i++)
        {
            tab_re[i] = tab_map->tab_registers[i];
        }
    }

    // ��������Ĵ���
    if (tab_input_re != NULL && tab_input_re_length > 0)
    {
        for (int i = 0; i < tab_input_re_length; i++)
        {
            tab_map->tab_input_registers[i] = tab_input_re[i];
        }
    }

    return 0;
}
/**
 * ָ������ Modbusӳ�䡣
 *
 * @param modbus_mapping_t  Ŀ��� maping��
 * @param type  ��Ҫ���µ����� @Type enum��
 * @param desnt Ŀ������ ��
 * @param len   Ŀ�����鳤�� ��
 * @return
 */
uint16_t slave_update_type(modbus_mapping_t *ctx_maping, Type type, void *desnt, uint8_t len)
{
    static uint8_t temp;
    temp = len;
    if (ctx_maping == NULL)
    {
        return 0;
    }

    if (type == Typetab_tab)
    {
        if (ctx_maping->nb_bits < temp)
            temp = ctx_maping->nb_bits; // Լ�� ��ֹ desnt ���ʹ��硣
        slave_update(ctx_maping, (uint8_t *)desnt, NULL, NULL, NULL, temp);
        return 1;
    }
    else if (type == Typetab_input)
    {
        if (ctx_maping->nb_input_bits < temp)
            temp = ctx_maping->nb_input_bits;
        slave_update(ctx_maping, NULL, (uint8_t *)desnt, NULL, NULL, temp);
        return 1;
    }
    else if (type == Typetab_re)
    {
        if (ctx_maping->nb_input_registers < temp)
            temp = ctx_maping->nb_input_registers;
        slave_update(ctx_maping, NULL, NULL, (uint16_t *)desnt, NULL, temp);
        return 1;
    }
    else if (type == Typetab_input_re)
    {
        if (ctx_maping->nb_registers < temp)
            temp = ctx_maping->nb_registers;
        slave_update(ctx_maping, NULL, NULL, NULL, (uint16_t *)desnt, temp);
        return 1;
    }
    else
    {
        return 0;
    }
}

//mapping Offset addres ƫ��ȥ�洢(��ʵ��)
